export default function (canvas, isRun) {

    function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

    let settings = {
        amplitudeX: 150,
        amplitudeY: 20,
        lines: 30,
        startColor: '#500c44',
        endColor: '#b4d455'
    };

    let c = canvas;
    let ctx = c.getContext("2d");
    let winW = window.innerWidth;
    let winH = window.innerHeight;
    let Paths = [];
    let color = [];
    let mouseY = 0;
    let mouseDown = false;
    let time = 0;
    let curves = undefined;
    let velocity = undefined;

    let Path = function () {
        function Path(y, color) {
            _classCallCheck(this, Path);

            this.y = y;
            this.color = color;
            this.root = [];
            this.create();
            this.draw();
        }

        Path.prototype.create = function create() {
            let rootX = 0;
            let rootY = this.y;

            this.root = [{ x: rootX, y: rootY }];

            while (rootX < winW) {
                let casual = Math.random() > 0.5 ? 1 : -1;
                let x = parseInt(settings.amplitudeX / 2 + Math.random() * settings.amplitudeX / 2);
                let y = parseInt(rootY + casual * (settings.amplitudeY / 2 + Math.random() * settings.amplitudeY / 2));
                rootX += x;
                let delay = Math.random() * 100;
                this.root.push({ x: rootX, y: y, height: rootY, casual: casual, delay: delay });
            }
        };

        Path.prototype.draw = function draw() {
            ctx.beginPath();
            ctx.moveTo(0, winH);

            ctx.lineTo(this.root[0].x, this.root[0].y);

            for (let i = 1; i < this.root.length - 1; i++) {

                let x = this.root[i].x;
                let y = this.root[i].y;
                let nextX = this.root[i + 1].x;
                let nextY = this.root[i + 1].y;

                let xMid = (x + nextX) / 2;
                let yMid = (y + nextY) / 2;
                let cpX1 = (xMid + x) / 2;
                let cpY1 = (yMid + y) / 2;
                let cpX2 = (xMid + nextX) / 2;
                let cpY2 = (yMid + nextY) / 2;

                ctx.quadraticCurveTo(cpX1, y, xMid, yMid);
                ctx.quadraticCurveTo(cpX2, nextY, nextX, nextY);
            }

            let lastPoint = this.root.reverse()[0];
            this.root.reverse();
            ctx.lineTo(lastPoint.x, lastPoint.y);
            ctx.lineTo(winW, winH);
            ctx.fillStyle = this.color;
            ctx.fill();
            ctx.closePath();
        };

        return Path;
    }();

    /* INIT */

    let path = undefined;
    function init() {
        c.width = winW;
        c.height = winH;
        Paths = [];

        color = chroma.scale([settings.startColor, settings.endColor]).mode('lch').colors(settings.lines);

        document.body.style = 'background: ' + settings.startColor;

        for (let i = 0; i < settings.lines; i++) {
            Paths.push(new Path(winH / settings.lines * i, color[i]));
            settings.startY = winH / settings.lines * i;
        }
    }

    /* WIN RESIZE */
    window.addEventListener('resize', function () {
        winW = window.innerWidth;
        winH = window.innerHeight;
        c.width = winW;
        c.height = winH;
        init();
    });
    window.dispatchEvent(new Event("resize"));

    /* RENDER */
    function render() {
        c.width = winW;
        c.height = winH;

        curves = mouseDown || isRun.value ? 2 : 4;
        velocity = mouseDown || isRun.value ? 6 : 0.8;

        time += mouseDown || isRun.value ? 0.1 : 0.05;

        Paths.forEach(function (path, i) {
            path.root.forEach(function (r, j) {
                if (j % curves == 1) {
                    let move = Math.sin(time + r.delay) * velocity * r.casual;
                    r.y -= move / 2 - move;
                }
                if (j + 1 % curves == 0) {
                    let move = Math.sin(time + r.delay) * velocity * r.casual;
                    r.x += move / 2 - move / 10;
                }
            });

            path.draw();
        });

        requestAnimationFrame(render);
    }
    render();

    /* MOUSEDOWN */
    'mousedown touchstart'.split(' ').forEach(function (e) {
        document.addEventListener(e, function () {
            mouseDown = true;
        });
    });

    /* MOUSEUP */
    'mouseup mouseleave touchend'.split(' ').forEach(function (e) {
        document.addEventListener(e, function () {
            mouseDown = false;
        });
    });

    /* MOUSEMOVE */
    'mousemove touchmove'.split(' ').forEach(function (e) {
        document.addEventListener(e, function (e) {
            mouseY = e.clientY || e.touches[0].clientY;
        });
    });
}